<?php

namespace app\api\controller\order;

use app\api\controller\Api;
use app\common\audit\logic\AuditResultLogic;
use app\common\customer\model\Customer;
use app\common\customer\model\CustomerAllocate;
use app\common\order\logic\IncomeLogic;
use app\common\order\logic\PaymentLogic;
use app\common\order\model\OrderAdditional;
use app\common\order\model\OrderCollect;
use app\common\order\model\OrderProduct;
use app\common\order\model\OrderIncome;
use app\common\order\validate\OrderIncomeValidate;
use app\common\order\validate\OrderProductValidate;
use app\common\order\validate\OrderValidate;
use app\common\system\logic\DepartmentLogic;
use app\common\system\logic\UserDepartmentLogic;
use app\common\system\logic\UserLogic;
use app\common\system\model\OperateLog;
use app\common\system\model\UserConfig;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\Exception;
use util\Format;

class Order extends Api
{
    public function index()
    {
        $post = $this->request->post();
        $user = $this->request->user;

        $where = [];
        $where[] = ['refund_status', '=', 0];
        $where[] = ['transfer_status', '=', 0];
        if ($user['user_type'] == 2) {
            $userLogic = new UserLogic();
            $staffIds = $userLogic->getDptUserIds($user['id']);
            $where[] = ['user_id', 'in', $staffIds];
        } else {
            $where[] = ['user_id', '=', $user['id']];
        }
        if (!empty($post['department_id'])) {
            $dptLogic = new UserDepartmentLogic();
            $staffIds = $dptLogic->getDptUserIds($post['department_id']);
            $where[] = ['user_id', 'in', $staffIds];
        }
        if (!empty($post['user_id'])) $where[] = ['user_id', 'in', $post['user_id']];
        if (!empty($post['company_id'])) $where[] = ['company_id', 'in', $post['company_id']];
        if (!empty($post['store_id'])) $where[] = ['store_id', 'in', $post['store_id']];
        if (!empty($post['category_id'])) $where[] = ['category_id', 'in', $post['category_id']];
        if (!empty($post['order_type'])) $where[] = ['order_type', 'in', $post['order_type']];
        if (!empty($post['check_status'])) $where[] = ['check_status', 'in', $post['check_status']];
        if (!empty($post['sign_date_range'])) {
            $signDateRange = Format::dateRange($post['sign_date_range']);
            $where[] = ['sign_date', 'between', $signDateRange];
        }
        if (!empty($post['event_date_range'])) {
            $eventDateRange = Format::dateRange($post['event_date_range']);
            $where[] = ['event_date', 'between', $eventDateRange];
        }
        if (!empty($post['keyword'])) $where[] = ['contact_no|bridegroom|bridegroom_mobile|bride|bride_mobile', 'like', "%{$post['keyword']}%"];

        list($cfg) = Format::pagination($post);
        $model = new \app\common\order\model\Order();
        $model = $model->where($where);
        if (!empty($post['service_company_id'])) {
            $hasMap = [];
            $hasMap[] = ['company_id', 'in', $post['service_company_id']];
            $model = $model->whereIn('id', function ($query) use ($hasMap) {
                $query->table('tk_order_product')->where($hasMap)->where('delete_time', 0)->field('order_id');
            });
        }
        if (!empty($post['source_id'])) {
            $hasWhere = [];
            $hasWhere[] = ['source_id', 'in', $post['source_id']];
            $model = $model->whereIn('member_id', function ($query) use ($hasWhere) {
                $query->table('tk_member')->where($hasWhere)->where('delete_time', 0)->field('id');
            });
        }
        $pg = $model->order('id desc')->paginate($cfg);
        $rows = $pg->getCollection();
        foreach ($rows as $row) {
            $row->append(['category', 'company', 'cooperation', 'user', 'store', 'hall', 'banquet_type', 'order_type_text', 'check_tag']);
        }

        // 返回接口数据
        $result['list'] = $rows;
        $result['pagination'] = Format::pgResult($pg);

        return success($result, '获取数据成功');
    }

    public function plan()
    {
        $post = $this->request->post();
        $user = $this->request->user;

        $where = [];
        if (!empty($post['user_id'])) $where[] = ['user_id', 'in', $post['user_id']];
        if (!empty($post['company_id'])) $where[] = ['company_id', 'in', $post['company_id']];
        if (!empty($post['store_id'])) $where[] = ['store_id', 'in', $post['store_id']];
        if (!empty($post['category_id'])) $where[] = ['category_id', 'in', $post['category_id']];
        if ($user['user_type'] == 2) { // 管理者
            $configModel = new UserConfig();
            $config = $configModel->where('id', $user['id'])->find();
            if (empty($config)) {
                $where[] = ['company_id', 'in', []];
            } else {
                $where[] = ['company_id', 'in', $config['company']];
            }
        }
        if (!empty($post['assign_status'])) $where[] = ['assign_status', '=', $post['assign_status']];
        if (!empty($post['order_type'])) $where[] = ['order_type', 'in', $post['order_type']];
        if (!empty($post['check_status'])) $where[] = ['check_status', 'in', $post['check_status']];
        if (!empty($post['sign_date_range'])) {
            $signDateRange = Format::dateRange($post['sign_date_range']);
            $where[] = ['sign_date', 'between', $signDateRange];
        }
        if (!empty($post['event_date_range'])) {
            $eventDateRange = Format::dateRange($post['event_date_range']);
            $where[] = ['event_date', 'between', $eventDateRange];
        }
        $where[] = ['refund_status', '=', 0];
        if (!empty($post['keyword'])) $where[] = ['contact_no|bridegroom|bridegroom_mobile|bride|bride_mobile', 'like', "%{$post['keyword']}%"];


        list($cfg) = Format::pagination($post);
        $model = new \app\common\order\model\Order();
        $model = $model->where($where);
        if (!empty($post['service_company_id'])) {
            $hasMap = [];
            $hasMap[] = ['company_id', 'in', $post['service_company_id']];
            $model = $model->whereIn('id', function ($query) use ($hasMap) {
                $query->table('tk_order_product')->where($hasMap)->field('order_id');
            });
        }
        if (!empty($post['source_id'])) {
            $hasWhere = [];
            $hasWhere[] = ['source_id', 'in', $post['source_id']];
            $model = $model->whereIn('member_id', function ($query) use ($hasWhere) {
                $query->table('tk_member')->where($hasWhere)->field('id');
            });
        }

        // 策划
        if ($user['user_type'] != 2) {
            $model = $model->whereIn('id', function ($query) use ($user) {
                $query->table('tk_order_user')->where('user_id', $user['id'])->where('role_id', 17)->field('order_id');
            });
        }

        if (!empty($post['planner_id'])) {
            $planWhere = [];
            $planWhere[] = ['user_id', 'in', $post['planner_id']];
            $planWhere[] = ['role_id', '=', 17];
            $model = $model->whereIn('id', function ($query) use ($planWhere) {
                $query->table('tk_order_user')->where($planWhere)->field('order_id');
            });
        }

        $pg = $model->order('id desc')->paginate($cfg);
        $rows = $pg->getCollection();
        foreach ($rows as $row) {
            $row->append(['category', 'company', 'cooperation', 'user', 'store', 'hall', 'banquet_type', 'order_type_text', 'check_tag']);
        }

        // 返回接口数据
        $result['list'] = $rows;
        $result['pagination'] = Format::pgResult($pg);

        return success($result, '获取数据成功');
    }

    public function refund()
    {
        $post = $this->request->post();
        $user = $this->request->user;

        $where = [];
        $where[] = ['refund_status', '=', '1'];
        if ($user['user_type'] == 2) {
            $userLogic = new UserLogic();
            $staffIds = $userLogic->getDptUserIds($user['id']);
            $where[] = ['user_id', 'in', $staffIds];
        } else {
            $where[] = ['user_id', '=', $user['id']];
        }
        if (!empty($post['department_id'])) {
            $dptLogic = new UserDepartmentLogic();
            $staffIds = $dptLogic->getDptUserIds($post['department_id']);
            $where[] = ['user_id', 'in', $staffIds];
        }
        if (!empty($post['user_id'])) $where[] = ['user_id', 'in', $post['user_id']];
        if (!empty($post['company_id'])) $where[] = ['company_id', 'in', $post['company_id']];
        if (!empty($post['store_id'])) $where[] = ['store_id', 'in', $post['store_id']];
        if (!empty($post['category_id'])) $where[] = ['category_id', 'in', $post['category_id']];
        if (!empty($post['order_type'])) $where[] = ['order_type', 'in', $post['order_type']];
        if (!empty($post['check_status'])) $where[] = ['check_status', 'in', $post['check_status']];
        if (!empty($post['sign_date_range'])) {
            $signDateRange = Format::dateRange($post['sign_date_range']);
            $where[] = ['sign_date', 'between', $signDateRange];
        }
        if (!empty($post['event_date_range'])) {
            $eventDateRange = Format::dateRange($post['event_date_range']);
            $where[] = ['event_date', 'between', $eventDateRange];
        }
        if (!empty($post['keyword'])) $where[] = ['contact_no|bridegroom|bridegroom_mobile|bride|bride_mobile', 'like', "%{$post['keyword']}%"];


        list($cfg) = Format::pagination($post);
        $model = new \app\common\order\model\Order();
        $model = $model->where($where);
        if (!empty($post['service_company_id'])) {
            $hasMap = [];
            $hasMap[] = ['company_id', 'in', $post['service_company_id']];
            $model = $model->whereIn('id', function ($query) use ($hasMap) {
                $query->table('tk_order_product')->where($hasMap)->field('order_id');
            });
        }
        if (!empty($post['source_id'])) {
            $hasWhere = [];
            $hasWhere[] = ['source_id', 'in', $post['source_id']];
            $model = $model->whereIn('member_id', function ($query) use ($hasWhere) {
                $query->table('tk_member')->where($hasWhere)->field('id');
            });
        }
        $pg = $model->order('id desc')->paginate($cfg);
        $rows = $pg->getCollection();
        foreach ($rows as $row) {
            $row->append(['category', 'company', 'cooperation', 'user', 'store', 'hall', 'banquet_type', 'order_type_text', 'check_tag']);
        }

        // 返回接口数据
        $result['list'] = $rows;
        $result['pagination'] = Format::pgResult($pg);

        return success($result, '获取数据成功');
    }

    // 订单详情
    public function detail()
    {
        $post = $this->request->post();
        if (empty($post['id'])) return error([], "参数错误");
        $result = [];

        $orderModel = new \app\common\order\model\Order();
        $order = $orderModel->where('id', $post['id'])->find();
        if (empty($order)) return error([], "订单不存在");

        // 订单基本信息
        $order->append(['category', 'company', 'cooperation', 'user', 'store', 'hall', 'banquet_type', 'order_type_text', 'collects', 'check_tag']);
        $result['order'] = $order;

        // 收款统计
        $incomeLogic = new IncomeLogic();
        $income = $incomeLogic->getBrief($post['id']);
        $income['uncollected'] = round($order['totals'] - $income['collected'], 2);
        $result['income'] = $income;

        // 付款
        $paymentLogic = new PaymentLogic();
        $result['payment'] = $paymentLogic->getBrief($post['id']);

        // 客资信息
        $customerModel = new Customer();
        $fields = "id,fullname,create_id,source_id";
        try {
            $customer = $customerModel->where('id', $order['member_id'])->field($fields)->find();
            $customer->append(['creator', 'source']);
            $result['customer'] = $customer;
        } catch (DataNotFoundException $e) {
            $result['customer'] = [
                'id' => '',
                'fullname' => '',
                'creator' => [
                    'id' => '',
                    'realname' => '',
                ],
                'source' => [
                    'id' => '',
                    'title' => ''
                ]
            ];
        }

        // 获取跟进人信息
        if ($order['allocate_id'] > 0) {
            $allocateModel = new CustomerAllocate();
            $allocate = $allocateModel->where('id', $order['allocate_id'])->field('id,user_id')->find();
            $allocate->append(['user']);
            $result['allocate'] = $allocate;
        }

        // 付款简介
        return success($result);
    }

    // 创建订单
    public function create()
    {
        $post = $this->request->post();

        $user = $this->request->user;
        if (!isset($post['order'])) {
            return error([], "缺少order参数");
        }

        if (!isset($post['products'])) {
            return error([], "缺少products参数");
        }

        if (!isset($post['income'])) {
            return error([], "缺少income参数");
        }

        // 验证订单基本信息
        $order = $post['order'];
        $orderValidate = new OrderValidate();
        if (!$orderValidate->check($order)) {
            return error([], $orderValidate->getError());
        }

        // 验证产品信息
        $products = $post['products'];
        foreach ($products as $product) {
            $orderProductValidate = new OrderProductValidate();
            if (!$orderProductValidate->check($product)) {
                return error([], $orderProductValidate->getError());
            }
        }

        // 验证收款信息
        $income = $post['income'];
        $incomeValidate = new OrderIncomeValidate();
        if (!$incomeValidate->check($income)) {
            return error([], $incomeValidate->getError());
        }

        $order['user_id'] = $user['id'];
        $order['order_no'] = date('YmdHis') . uniqid();
        $model = new \app\common\order\model\Order();
        $model->startTrans();
        $source = [];
        try {
            $model->save($order);
            $orderId = $model->id;

            $modelName = \app\common\order\model\Order::class;
            $source[$modelName] = $orderId;
        } catch (DbException $e) {
            $model->rollback();
            return error([], $e->getMessage());
        }

        // 同步收款计划
        $collects = $post['order']['collects'];
        foreach ($collects as &$row) {
            $row['order_id'] = $orderId;
            $row['collect_date'] = strtotime($row['collect_date']);
            $row['create_time'] = time();
            $row['update_time'] = time();
        }

        try {
            $collectModel = new OrderCollect();
            $collectModel->insertAll($collects);
        } catch (DbException $e) {
            $model->rollback();
            return error([], $e->getMessage());
        }

        // 服务类型
        $modelName = OrderProduct::class;
        foreach ($products as $row) {
            $orderProductModel = new OrderProduct();
            $row['order_id'] = $orderId;
            $row['user_id'] = $user['id'];
            try {
                $orderProductModel->save($row);
                $source[$modelName][] = $orderProductModel->id;
            } catch (DbException $e) {
                $model->rollback();
                return error([], $e->getMessage());
            }
        }

        // 收款信息
        $income['order_id'] = $orderId;
        $income['user_id'] = $user['id'];
        $incomeModel = new OrderIncome();
        $modelName = OrderIncome::class;
        try {
            $incomeModel->save($income);
            $source[$modelName] = $incomeModel->id;
        } catch (DbException $e) {
            $model->rollback();
            return error([], $e->getMessage());
        }

        // 添加增项
        if (!empty($post['additional'])) {
            $modelName = OrderAdditional::class;
            $additional = $post['additional'];
            foreach ($additional as $row) {
                try {
                    $row['order_id'] = $orderId;
                    $row['user_id'] = $user['id'];
                    $additionalModel = new OrderAdditional();
                    $additionalModel->save($row);
                    $source[$modelName][] = $additionalModel->id;
                } catch (DbException $e) {
                    $model->rollback();
                    return error([], $e->getMessage());
                }
            }
        }

        // 未找到审核流程可重新发起暂存
        // if ($order['check_status'] == -1) {
        //     return success([], "暂存成功");
        // }

        $auditRsLogic = new AuditResultLogic();
        $master = $model->getData();
        $options = [
            'company_id' => $master['company_id'],
            'timing' => 'order'
        ];
        try {
            $auditNo = $auditRsLogic->initAudit($master, $user, $source, $options);
            foreach ($source as $className => $row) {
                try {
                    $where = [];
                    if (is_array($row)) {
                        $where[] = ['id', 'in', $row];
                    } else {
                        $where[] = ['id', '=', $row];
                    }
                    $class = new $className;
                    $class->where($where)->save(['check_no' => $auditNo]);
                } catch (DbException $e) {
                    return error([], $e->getMessage());
                }
            }
            $model->commit();

            return success([], '创建订单成功');
        } catch (Exception $e) {
            $msg = $e->getMessage();
        } catch (DbException $e) {
            $msg = $e->getMessage();
        }
        return error([], $msg, 404);
    }

    public function save()
    {
        $post = $this->request->post();

        $user = $this->request->user;
        if (!isset($post['order'])) {
            return error([], "缺少order参数");
        }

        if (!isset($post['products'])) {
            return error([], "缺少products参数");
        }

        if (!isset($post['income'])) {
            return error([], "缺少income参数");
        }

        // 验证订单基本信息
        $order = $post['order'];
        $orderValidate = new OrderValidate();
        if (!$orderValidate->check($order)) {
            return error([], $orderValidate->getError());
        }

        // 验证产品信息
        $products = $post['products'];
        foreach ($products as $product) {
            $orderProductValidate = new OrderProductValidate();
            if (!$orderProductValidate->check($product)) {
                return error([], $orderProductValidate->getError());
            }
        }

        // 验证收款信息
        $income = $post['income'];
        $incomeValidate = new OrderIncomeValidate();
        if (!$incomeValidate->check($income)) {
            return error([], $incomeValidate->getError());
        }

        $order['user_id'] = $user['id'];
        $model = new \app\common\order\model\Order();
        $model->startTrans();
        $source = [];
        try {
            $orderRow = $model->where('id', $order['id'])->find();
            $orderRow->save($order);
            $orderId = $order['id'];

            $modelName = \app\common\order\model\Order::class;
            $source[$modelName] = $orderId;
        } catch (DbException $e) {
            $model->rollback();
            return error([], $e->getMessage());
        }

        // 同步收款计划
        $collects = $post['order']['collects'];
        $collectModel = new OrderCollect();
        foreach ($collects as &$row) {
            $row['order_id'] = $orderId;
            $collect = $collectModel->where('id', $row['id'])->find();
            $collect->save($row);
        }

        // 服务类型
        $modelName = OrderProduct::class;
        foreach ($products as $row) {

            $row['order_id'] = $orderId;
            $row['user_id'] = $user['id'];
            try {
                $orderProductModel = new OrderProduct();
                if ($row['id']) {
                    $product = $orderProductModel->where('id', $row['id'])->find();
                    $product->save($row);
                    $source[$modelName][] = $row['id'];
                } else {
                    $orderProductModel->save($row);
                    $source[$modelName][] = $orderProductModel->id;
                }
            } catch (DbException $e) {
                $model->rollback();
                return error([], $e->getMessage());
            }
        }

        // 收款信息
        $income['order_id'] = $orderId;
        $income['user_id'] = $user['id'];
        $incomeModel = new OrderIncome();
        $modelName = OrderIncome::class;
        try {
            $incomeRow = $incomeModel->where('id', $income['id'])->find();
            $incomeRow->save($income);
            $source[$modelName] = $income['id'];
        } catch (DbException $e) {
            $model->rollback();
            return error([], $e->getMessage());
        }

        // 添加增项
        if (!empty($post['additional'])) {
            $modelName = OrderAdditional::class;
            $additionals = $post['additional'];
            foreach ($additionals as $row) {
                try {
                    $row['order_id'] = $orderId;
                    $row['user_id'] = $user['id'];
                    $additionalModel = new OrderAdditional();
                    if ($row['id']) {
                        $additional = $additionalModel->where('id', $row['id'])->find();
                        $additional->save($row);
                        $source[$modelName][] = $row['id'];
                    } else {
                        $additionalModel->save($row);
                        $source[$modelName][] = $additionalModel->id;
                    }
                } catch (DbException $e) {
                    $model->rollback();
                    return error([], $e->getMessage());
                }
            }
        }

        // 未找到审核流程可重新发起暂存
        // if ($order['check_status'] == -1) {
        //     return success([], "暂存成功");
        // }

        $auditRsLogic = new AuditResultLogic();
        $master = $orderRow->getData();
        $options = [
            'company_id' => $master['company_id'],
            'timing' => 'order'
        ];
        try {
            $auditNo = $auditRsLogic->initAudit($master, $user, $source, $options);
            foreach ($source as $className => $row) {
                try {
                    $where = [];
                    if (is_array($row)) {
                        $where[] = ['id', 'in', $row];
                    } else {
                        $where[] = ['id', '=', $row];
                    }
                    $class = new $className;
                    $class->where($where)->save(['check_no' => $auditNo]);
                } catch (DbException $e) {
                    return error([], $e->getMessage());
                }
            }
            $model->commit();

            return success([], '创建订单成功');
        } catch (Exception $e) {
            $msg = $e->getMessage();
        } catch (DbException $e) {
            $msg = $e->getMessage();
        }
        return error([], $msg, 404);
    }

    public function update()
    {
        $post = $this->request->post();
        $user = $this->request->user;

        $orderValidate = new OrderValidate();
        if (!$orderValidate->check($post)) {
            return error([], $orderValidate->getError());
        }

        $model = new \app\common\order\model\Order();
        $row = $model->where('id', $post['id'])->find();
        if (empty($row)) return error([], '数据已不存在');

        $model->startTrans();
        try {
            $post['user_id'] = $user['id'];
            $origin = $row->getData();
            $row->save($post);

            $changed = $row->getData();
            $modelName = \app\common\order\model\Order::class;
            OperateLog::write($user['id'], $post['id'], $origin, $changed, $modelName);
        } catch (DbException $e) {
            $model->rollback();
            return error([], $e->getMessage());
        }
        $model->commit();

        return success([], '更新成功');
    }

    public function doRefund()
    {
        $post = $this->request->post();
        $user = $this->request->user;

        if (empty($post['id'])) return error([], "参数错误");

        $model = new \app\common\order\model\Order();
        $row = $model->field('id,refund_status')->where('id', $post['id'])->find();
        if (empty($row)) return error([], '数据已不存在');

        $model->startTrans();
        try {
            $origin = $row->getData();
            $post['refund_status'] = 1;
            $row->save($post);

            $changed = $row->getData();
            $modelName = \app\common\order\model\Order::class;
            OperateLog::write($user['id'], $post['id'], $origin, $changed, $modelName);
        } catch (DbException $e) {
            $model->rollback();
            return error([], $e->getMessage());
        }
        $model->commit();

        return success([], '退单成功');
    }
}